package org.htmlcleaner;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;

public abstract class HtmlTokenizer
{
  private static final int WORKING_BUFFER_SIZE = 1024;
  private boolean _asExpected = true;
  private transient TagToken _currentTagToken = null;
  private transient DoctypeToken _docType = null;
  private boolean _isScriptContext = false;
  private transient int _len = -1;
  private transient int _pos = 0;
  private BufferedReader _reader;
  private transient char[] _saved = new char[512];
  private transient int _savedLen = 0;
  private transient List<BaseToken> _tokenList = new ArrayList();
  private char[] _working = new char[1024];
  private StringBuilder commonStr = new StringBuilder();
  private boolean isAllowHtmlInsideAttributes;
  private boolean isAllowMultiWordAttributes;
  private boolean isNamespacesAware;
  private boolean isOmitComments;
  private boolean isOmitDeprecatedTags;
  private boolean isOmitUnknownTags;
  private boolean isTreatDeprecatedTagsAsContent;
  private boolean isTreatUnknownTagsAsContent;
  private CleanerProperties props;
  private ITagInfoProvider tagInfoProvider;
  private CleanerTransformations transformations;

  public HtmlTokenizer(Reader paramReader, CleanerProperties paramCleanerProperties, CleanerTransformations paramCleanerTransformations, ITagInfoProvider paramITagInfoProvider)
    throws IOException
  {
    this._reader = new BufferedReader(paramReader);
    this.props = paramCleanerProperties;
    this.isOmitUnknownTags = paramCleanerProperties.isOmitUnknownTags();
    this.isTreatUnknownTagsAsContent = paramCleanerProperties.isTreatUnknownTagsAsContent();
    this.isOmitDeprecatedTags = paramCleanerProperties.isOmitDeprecatedTags();
    this.isTreatDeprecatedTagsAsContent = paramCleanerProperties.isTreatDeprecatedTagsAsContent();
    this.isNamespacesAware = paramCleanerProperties.isNamespacesAware();
    this.isOmitComments = paramCleanerProperties.isOmitComments();
    this.isAllowMultiWordAttributes = paramCleanerProperties.isAllowMultiWordAttributes();
    this.isAllowHtmlInsideAttributes = paramCleanerProperties.isAllowHtmlInsideAttributes();
    this.transformations = paramCleanerTransformations;
    this.tagInfoProvider = paramITagInfoProvider;
  }

  private boolean addSavedAsContent()
  {
    int i = this._savedLen;
    int j = 0;
    if (i > 0)
    {
      addToken(new ContentNode(this._saved, this._savedLen));
      this._savedLen = 0;
      j = 1;
    }
    return j;
  }

  private void addToken(BaseToken paramBaseToken)
  {
    this._tokenList.add(paramBaseToken);
    makeTree(this._tokenList);
  }

  private String attributeValue()
    throws IOException
  {
    skipWhitespaces();
    if ((isCharSimple('<')) || (isCharSimple('>')) || (startsWithSimple("/>")))
      return "";
    int i = 0;
    this.commonStr.delete(0, this.commonStr.length());
    int j;
    if (isCharSimple('\''))
    {
      j = 1;
      saveCurrentSafe();
      go();
    }
    while ((!isAllRead()) && ((((j != 0) && (!isCharEquals('\''))) || ((((i == 0) || (isCharEquals('"')) || ((!this.isAllowHtmlInsideAttributes) && (((isCharEquals('>')) || (isCharEquals('<'))))) || ((!this.isAllowMultiWordAttributes) && (isWhitespaceSafe())))) && (((j != 0) || (i != 0) || (isWhitespaceSafe()) || (isCharEquals('>')) || (isCharEquals('<'))))))))
    {
      if (isValidXmlCharSafe())
      {
        this.commonStr.append(this._working[this._pos]);
        saveCurrentSafe();
      }
      go();
      continue;
      boolean bool = isCharSimple('"');
      j = 0;
      i = 0;
      if (!bool)
        continue;
      i = 1;
      saveCurrentSafe();
      go();
      j = 0;
    }
    if ((isCharSimple('\'')) && (j != 0))
    {
      saveCurrentSafe();
      go();
    }
    while (true)
    {
      return this.commonStr.toString();
      if ((!isCharSimple('"')) || (i == 0))
        continue;
      saveCurrentSafe();
      go();
    }
  }

  private void comment()
    throws IOException
  {
    go(4);
    while ((!isAllRead()) && (!startsWithSimple("-->")))
    {
      if (isValidXmlCharSafe())
        saveCurrentSafe();
      go();
    }
    if (startsWithSimple("-->"))
      go(3);
    if (this._savedLen <= 0)
      return;
    if (!this.isOmitComments)
    {
      String str1 = this.props.getHyphenReplacementInComment();
      String str2 = new String(this._saved, 0, this._savedLen).replaceAll("--", str1 + str1);
      if ((str2.length() > 0) && (str2.charAt(0) == '-'))
        str2 = str1 + str2.substring(1);
      int i = str2.length();
      if ((i > 0) && (str2.charAt(i - 1) == '-'))
        str2 = str2.substring(0, i - 1) + str1;
      addToken(new CommentNode(str2));
    }
    this._savedLen = 0;
  }

  private boolean content()
    throws IOException
  {
    do
    {
      if (isAllRead())
        break;
      if (isValidXmlCharSafe())
        saveCurrentSafe();
      go();
    }
    while (!isCharSimple('<'));
    return addSavedAsContent();
  }

  private void doctype()
    throws IOException
  {
    go(9);
    skipWhitespaces();
    String str1 = identifier();
    skipWhitespaces();
    String str2 = identifier();
    skipWhitespaces();
    String str3 = attributeValue();
    skipWhitespaces();
    String str4 = attributeValue();
    ignoreUntil('<');
    this._docType = new DoctypeToken(str1, str2, str3, str4);
  }

  private char getCurrentChar()
  {
    return this._working[this._pos];
  }

  private void go()
    throws IOException
  {
    this._pos = (1 + this._pos);
    readIfNeeded(0);
  }

  private void go(int paramInt)
    throws IOException
  {
    this._pos = (paramInt + this._pos);
    readIfNeeded(paramInt - 1);
  }

  private String identifier()
    throws IOException
  {
    String str1 = null;
    this._asExpected = true;
    if (!isIdentifierStartChar())
      this._asExpected = false;
    int j;
    do
    {
      int i;
      do
      {
        return str1;
        this.commonStr.delete(0, this.commonStr.length());
        while ((!isAllRead()) && (isIdentifierChar()))
        {
          saveCurrentSafe();
          this.commonStr.append(this._working[this._pos]);
          go();
        }
        while ((this.commonStr.length() > 0) && (Utils.isIdentifierHelperChar(this.commonStr.charAt(-1 + this.commonStr.length()))))
          this.commonStr.deleteCharAt(-1 + this.commonStr.length());
        i = this.commonStr.length();
        str1 = null;
      }
      while (i == 0);
      str1 = this.commonStr.toString();
      j = str1.indexOf(':');
    }
    while (j < 0);
    String str2 = str1.substring(0, j);
    String str3 = str1.substring(j + 1);
    int k = str3.indexOf(':');
    if (k >= 0)
      str3 = str3.substring(0, k);
    if (this.isNamespacesAware)
      return str2 + ":" + str3;
    return str3;
  }

  private void ignoreUntil(char paramChar)
    throws IOException
  {
    do
    {
      if (isAllRead())
        return;
      go();
    }
    while (!isChar(paramChar));
  }

  private boolean isAllRead()
  {
    return (this._len >= 0) && (this._pos >= this._len);
  }

  private boolean isChar(char paramChar)
  {
    return isChar(this._pos, paramChar);
  }

  private boolean isChar(int paramInt, char paramChar)
  {
    if ((this._len >= 0) && (paramInt >= this._len));
    do
      return false;
    while (Character.toLowerCase(paramChar) != Character.toLowerCase(this._working[paramInt]));
    return true;
  }

  private boolean isCharEquals(char paramChar)
  {
    return this._working[this._pos] == paramChar;
  }

  private boolean isCharSimple(char paramChar)
  {
    return (((this._len < 0) || (this._pos < this._len))) && (paramChar == this._working[this._pos]);
  }

  private boolean isIdentifierChar()
  {
    if ((this._len >= 0) && (this._pos >= this._len));
    char c;
    do
    {
      return false;
      c = this._working[this._pos];
    }
    while ((!Character.isUnicodeIdentifierStart(c)) && (!Character.isDigit(c)) && (!Utils.isIdentifierHelperChar(c)));
    return true;
  }

  private boolean isIdentifierStartChar()
  {
    return isIdentifierStartChar(this._pos);
  }

  private boolean isIdentifierStartChar(int paramInt)
  {
    if ((this._len >= 0) && (paramInt >= this._len));
    char c;
    do
    {
      return false;
      c = this._working[paramInt];
    }
    while ((!Character.isUnicodeIdentifierStart(c)) && (c != '_'));
    return true;
  }

  private boolean isReservedTag(String paramString)
  {
    String str = paramString.toLowerCase();
    return ("html".equals(str)) || ("head".equals(str)) || ("body".equals(str));
  }

  private boolean isValidXmlChar()
  {
    return (isAllRead()) || (Utils.isValidXmlChar(this._working[this._pos]));
  }

  private boolean isValidXmlCharSafe()
  {
    return Utils.isValidXmlChar(this._working[this._pos]);
  }

  private boolean isWhitespace()
  {
    return isWhitespace(this._pos);
  }

  private boolean isWhitespace(int paramInt)
  {
    if ((this._len >= 0) && (paramInt >= this._len))
      return false;
    return Character.isWhitespace(this._working[paramInt]);
  }

  private boolean isWhitespaceSafe()
  {
    return Character.isWhitespace(this._working[this._pos]);
  }

  private void readIfNeeded(int paramInt)
    throws IOException
  {
    if ((this._len != -1) || (paramInt + this._pos < 1024))
      return;
    int i = 1024 - this._pos;
    System.arraycopy(this._working, this._pos, this._working, 0, i);
    this._pos = 0;
    int j = 1024 - i;
    int k = 0;
    int l = i;
    int i1;
    do
    {
      i1 = this._reader.read(this._working, l, j);
      if (i1 < 0)
        continue;
      k += i1;
      l += i1;
      j -= i1;
    }
    while ((i1 >= 0) && (j > 0));
    if (j > 0)
      this._len = (k + i);
    int i2 = 0;
    label127: if (this._len >= 0);
    for (int i3 = this._len; i2 < i3; i3 = 1024)
    {
      int i4 = this._working[i2];
      if ((i4 >= 1) && (i4 <= 32) && (i4 != 10) && (i4 != 13))
        this._working[i2] = ' ';
      ++i2;
      break label127:
    }
  }

  private void save(char paramChar)
  {
    if (this._savedLen >= this._saved.length)
    {
      char[] arrayOfChar2 = new char[512 + this._saved.length];
      System.arraycopy(this._saved, 0, arrayOfChar2, 0, this._saved.length);
      this._saved = arrayOfChar2;
    }
    char[] arrayOfChar1 = this._saved;
    int i = this._savedLen;
    this._savedLen = (i + 1);
    arrayOfChar1[i] = paramChar;
  }

  private void saveCurrent()
  {
    if (isAllRead())
      return;
    save(this._working[this._pos]);
  }

  private void saveCurrent(int paramInt)
    throws IOException
  {
    readIfNeeded(paramInt);
    int i = this._pos;
    while ((!isAllRead()) && (paramInt > 0))
    {
      save(this._working[i]);
      ++i;
      --paramInt;
    }
  }

  private void saveCurrentSafe()
  {
    save(this._working[this._pos]);
  }

  private void skipWhitespaces()
    throws IOException
  {
    while ((!isAllRead()) && (isWhitespaceSafe()))
    {
      saveCurrentSafe();
      go();
    }
  }

  private boolean startsWith(String paramString)
    throws IOException
  {
    int i = paramString.length();
    readIfNeeded(i);
    if ((this._len >= 0) && (i + this._pos > this._len))
      return false;
    for (int j = 0; j < i; ++j)
      if (Character.toLowerCase(paramString.charAt(j)) != Character.toLowerCase(this._working[(j + this._pos)]));
    return true;
  }

  private boolean startsWithSimple(String paramString)
    throws IOException
  {
    int i = paramString.length();
    readIfNeeded(i);
    if ((this._len >= 0) && (i + this._pos > this._len))
      return false;
    for (int j = 0; j < i; ++j)
      if (paramString.charAt(j) != this._working[(j + this._pos)]);
    return true;
  }

  private void tagAttributes()
    throws IOException
  {
    label0: String str1;
    while (true)
    {
      if ((isAllRead()) || (!this._asExpected) || (isCharSimple('>')) || (startsWithSimple("/>")))
        return;
      skipWhitespaces();
      str1 = identifier();
      if (this._asExpected)
        break;
      if ((!isCharSimple('<')) && (!isCharSimple('>')) && (!startsWithSimple("/>")))
      {
        if (isValidXmlChar())
          saveCurrent();
        go();
      }
      if (isCharSimple('<'))
        continue;
      this._asExpected = true;
    }
    skipWhitespaces();
    if (isCharSimple('='))
    {
      saveCurrentSafe();
      go();
    }
    for (String str2 = attributeValue(); ; str2 = str1)
      while (true)
      {
        if (this._asExpected);
        this._currentTagToken.setAttribute(str1, str2);
        break label0:
        if ("empty".equals(this.props.booleanAttributeValues))
          str2 = "";
        if (!"true".equals(this.props.booleanAttributeValues))
          break;
        str2 = "true";
      }
  }

  private void tagEnd()
    throws IOException
  {
    saveCurrent(2);
    go(2);
    if (isAllRead())
      return;
    String str = identifier();
    if ((this.transformations != null) && (this.transformations.hasTransformationForTag(str)))
    {
      TagTransformation localTagTransformation = this.transformations.getTransformation(str);
      if (localTagTransformation != null)
        str = localTagTransformation.getDestTag();
    }
    if (str != null)
    {
      TagInfo localTagInfo = this.tagInfoProvider.getTagInfo(str);
      if (((localTagInfo == null) && (!this.isOmitUnknownTags) && (this.isTreatUnknownTagsAsContent) && (!isReservedTag(str))) || ((localTagInfo != null) && (localTagInfo.isDeprecated()) && (!this.isOmitDeprecatedTags) && (this.isTreatDeprecatedTagsAsContent)))
      {
        content();
        return;
      }
    }
    this._currentTagToken = new EndTagToken(str);
    if (this._asExpected)
    {
      skipWhitespaces();
      tagAttributes();
      if (str != null)
        addToken(this._currentTagToken);
      if (isCharSimple('>'))
        go();
      if ("script".equalsIgnoreCase(str))
        this._isScriptContext = false;
      this._currentTagToken = null;
      return;
    }
    addSavedAsContent();
  }

  private void tagStart()
    throws IOException
  {
    saveCurrent();
    go();
    if (isAllRead())
      return;
    String str = identifier();
    CleanerTransformations localCleanerTransformations = this.transformations;
    TagTransformation localTagTransformation = null;
    if (localCleanerTransformations != null)
    {
      boolean bool = this.transformations.hasTransformationForTag(str);
      localTagTransformation = null;
      if (bool)
      {
        localTagTransformation = this.transformations.getTransformation(str);
        if (localTagTransformation != null)
          str = localTagTransformation.getDestTag();
      }
    }
    if (str != null)
    {
      TagInfo localTagInfo = this.tagInfoProvider.getTagInfo(str);
      if (((localTagInfo == null) && (!this.isOmitUnknownTags) && (this.isTreatUnknownTagsAsContent) && (!isReservedTag(str))) || ((localTagInfo != null) && (localTagInfo.isDeprecated()) && (!this.isOmitDeprecatedTags) && (this.isTreatDeprecatedTagsAsContent)))
      {
        content();
        return;
      }
    }
    TagNode localTagNode = createTagNode(str);
    this._currentTagToken = localTagNode;
    if (this._asExpected)
    {
      skipWhitespaces();
      tagAttributes();
      if (str != null)
      {
        if (localTagTransformation != null)
          localTagNode.transformAttributes(localTagTransformation);
        addToken(this._currentTagToken);
      }
      if (isCharSimple('>'))
      {
        go();
        if ("script".equalsIgnoreCase(str))
          this._isScriptContext = true;
      }
      while (true)
      {
        this._currentTagToken = null;
        return;
        if (!startsWithSimple("/>"))
          continue;
        go(2);
        if (!"script".equalsIgnoreCase(str))
          continue;
        addToken(new EndTagToken(str));
      }
    }
    addSavedAsContent();
  }

  abstract TagNode createTagNode(String paramString);

  public DoctypeToken getDocType()
  {
    return this._docType;
  }

  List<BaseToken> getTokenList()
  {
    return this._tokenList;
  }

  abstract void makeTree(List<BaseToken> paramList);

  void start()
    throws IOException
  {
    this._currentTagToken = null;
    this._tokenList.clear();
    this._asExpected = true;
    this._isScriptContext = false;
    int i = 0;
    this._pos = 1024;
    readIfNeeded(0);
    int j = 1;
    while (!isAllRead())
    {
      label40: this._savedLen = 0;
      this._currentTagToken = null;
      this._asExpected = true;
      readIfNeeded(10);
      if (this._isScriptContext)
      {
        if ((startsWith("</script")) && (((isWhitespace(8 + this._pos)) || (isChar(8 + this._pos, '>')))))
          tagEnd();
        while (true)
        {
          if (!this._isScriptContext);
          j = 1;
          break label40:
          if ((j != 0) && (startsWithSimple("<!--")))
            comment();
          boolean bool = content();
          if ((j == 0) || (!bool))
            continue;
          BaseToken localBaseToken = (BaseToken)this._tokenList.get(-1 + this._tokenList.size());
          if (localBaseToken == null)
            continue;
          String str = localBaseToken.toString();
          if ((str == null) || (str.trim().length() <= 0))
            continue;
          j = 0;
        }
      }
      if (startsWith("<!doctype"))
      {
        if (i == 0)
        {
          doctype();
          i = 1;
        }
        ignoreUntil('<');
      }
      if ((startsWithSimple("</")) && (isIdentifierStartChar(2 + this._pos)))
      {
        i = 1;
        tagEnd();
      }
      if (startsWithSimple("<!--"))
        comment();
      if ((startsWithSimple("<")) && (isIdentifierStartChar(1 + this._pos)))
      {
        i = 1;
        tagStart();
      }
      if ((this.props.isIgnoreQuestAndExclam()) && (((startsWithSimple("<!")) || (startsWithSimple("<?")))))
      {
        ignoreUntil('>');
        if (!isCharSimple('>'))
          continue;
        go();
      }
      content();
    }
    this._reader.close();
  }
}

/* Location:           D:\soft\dex2jar-0.0.9.15\classes-dex2jar.jar
 * Qualified Name:     org.htmlcleaner.HtmlTokenizer
 * JD-Core Version:    0.5.4
 */